/**
 * @file    smk_rs485.c
 * @brief   逆变器协议-SMK-RS485协议
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-11-14
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-11-14 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "smk_rs485.h"
#include "modbus_app.h"
#include "if_di.h"
#include "cfg_prj.h"
#include "sample.h"
#include "parallel_com.h"
#include "var_mng.h"
#include "param_mng.h"
/* macro/define --------------------------------------------------------------*/

/* typedef -------------------------------------------------------------------*/
#define IN1_REG_ST       (19)
#define IN1_REG_END      (36)  // 多+1防止溢出
#define IN1_REG_SIZE     (IN1_REG_END - IN1_REG_ST + 1)
#define IN2_REG_ST       (100)
#define IN2_REG_END      (117) // 多+1防止溢出
#define IN2_REG_SIZE     (IN2_REG_END - IN2_REG_ST + 1)

#define CMD_READ_IN_REG      (0x03)
/* local functions -----------------------------------------------------------*/
static void smk_read_input_reg(md_data_type md_data_msg , uint8_t *tx_buf ,uint16_t *tx_len);
static void smk_update_in1_reg(void);
static void smk_update_in2_reg(void);
static uint16_t smk_get_sys_state(void);
/* static variables ----------------------------------------------------------*/
static uint16_t input_reg1_buf[IN1_REG_SIZE] = {0};
static uint16_t input_reg2_buf[IN2_REG_SIZE] = {0};
/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
uint8_t smk_rs485_analysis(uint8_t *rx_buf , uint16_t rx_len ,uint8_t *tx_buf , uint16_t *tx_len)
{
    md_data_type recv_md_data = {0};
    if(TRUE == modbus_rtu_analysis(rx_buf , rx_len , &recv_md_data))
    {
        if(1 == recv_md_data.addr)
        {
            if(CMD_READ_IN_REG == recv_md_data.cmd_code)
            {
                if((recv_md_data.reg_addr >= IN1_REG_ST)
                 && (recv_md_data.reg_addr + recv_md_data.data_len <= IN1_REG_END))
                {
                    smk_update_in1_reg();
					smk_read_input_reg(recv_md_data , tx_buf , tx_len);
					return TRUE;
                }
                if((recv_md_data.reg_addr >= IN2_REG_ST)
                 && (recv_md_data.reg_addr + recv_md_data.data_len <= IN2_REG_END))
                {
                    smk_update_in2_reg();
					smk_read_input_reg(recv_md_data , tx_buf , tx_len);
					return TRUE;
                }
                else
                {
                    return FALSE;
                }
            }
            return FALSE;
        }
        return FALSE;
    }
    return FALSE;
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
static void smk_read_input_reg(md_data_type md_data_msg , uint8_t *tx_buf ,uint16_t *tx_len)
{
    uint16_t data_len = 0;
    uint16_t crc_code = 0;
    uint8_t i = 0;
    uint8_t *p_tx = tx_buf;
	uint16_t idx_cnt = 0;
	uint16_t *p_reg = 0;
	uint16_t start_addr = 0;

    p_tx[idx_cnt ++] = md_data_msg.addr;
    p_tx[idx_cnt ++] = md_data_msg.cmd_code;
    data_len = md_data_msg.data_len * 2;
    p_tx[idx_cnt ++] = data_len; 
    
	if((md_data_msg.reg_addr >= IN1_REG_ST)
      && (md_data_msg.reg_addr + md_data_msg.data_len <= IN1_REG_END))
	{
		p_reg = input_reg1_buf;
		start_addr = md_data_msg.reg_addr - IN1_REG_ST;
	}
	else
	{
		start_addr = md_data_msg.reg_addr - IN2_REG_ST;
		p_reg = input_reg2_buf;
	}
	
    for (i = 0; i < md_data_msg.data_len; ++i) 
	{
        p_tx[idx_cnt ++] = p_reg[i + start_addr] >> 8;
		p_tx[idx_cnt ++] = p_reg[i + start_addr];
    }

    crc_code = modbus_calc_crc(tx_buf, idx_cnt);

    p_tx[idx_cnt ++] = crc_code & 0xff;
    p_tx[idx_cnt ++] = crc_code >> 8;

    *tx_len = idx_cnt;   //修改
}

static void smk_update_in1_reg(void)
{
    int32_t sys_curr = 0;
	uint32_t cap_val = 0;
    input_reg1_buf[0] = smk_get_sys_state();
    input_reg1_buf[1] = 0;
    input_reg1_buf[2] = master_data_reg.avg_soc;
    input_reg1_buf[3] = master_data_reg.avg_batt_volt;
    input_reg1_buf[4] = master_data_reg.total_bus_curr;	
	input_reg1_buf[5] = 0;
    input_reg1_buf[6] = var_get_data(VAR_ID_TP_SOP_CC) * 10;
	
	cap_val = master_data_reg.total_real_cap;
	if(cap_val >= MAX_DISP_CAP)
		cap_val = MAX_DISP_CAP;
    input_reg1_buf[7] = cap_val;
	
	cap_val = master_data_reg.total_full_cap;
	if(cap_val >= MAX_DISP_CAP)
		cap_val = MAX_DISP_CAP;
    input_reg1_buf[8] = cap_val;
    input_reg1_buf[9] = 0;
    input_reg1_buf[10] = 0;
    input_reg1_buf[11] = 0;
    input_reg1_buf[12] = 0;
    input_reg1_buf[13] = 0;
    input_reg1_buf[14] = var_get_data(VAR_ID_TP_SOP_CV) * 10;
    input_reg1_buf[15] = 0;
    input_reg1_buf[16] = var_get_data(VAR_ID_TP_SOP_DC) * 10;
}

static void smk_update_in2_reg(void)
{
    int32_t sys_curr = 0;
    input_reg2_buf[0] = master_data_reg.avg_batt_volt * 0.1;
    sys_curr = master_data_reg.total_bus_curr * 0.1;

    if(sys_curr > 0)
        input_reg2_buf[1] = sys_curr;
    else
        input_reg2_buf[1] = 0;

    if(sys_curr < 0)
        input_reg2_buf[2] = -sys_curr;
    else
        input_reg2_buf[2] = 0;

    input_reg2_buf[3] = var_get_data(VAR_ID_TP_FULL_CAP) * 0.1;
    input_reg2_buf[4] = var_get_data(VAR_ID_TP_REAL_CAP) * 0.1;
    input_reg2_buf[5] = master_data_reg.avg_soc;
	input_reg2_buf[6] = master_data_reg.avg_max_temp -2731.5;	
    input_reg2_buf[7] = 0;
    input_reg2_buf[8] = 0;
    input_reg2_buf[9] = 0;
    input_reg2_buf[10] = var_get_data(VAR_ID_TP_SOP_CV);
    input_reg2_buf[11] = var_get_data(VAR_ID_TP_SOP_DV);
    input_reg2_buf[12] = var_get_data(VAR_ID_TP_SOP_CC);
    input_reg2_buf[13] = var_get_data(VAR_ID_TP_SOP_DC);
    input_reg2_buf[14] = parallel_get_pcs_ctrl(PARALLEL_PCS_FROCE_CHG1);
    input_reg2_buf[15] = parallel_get_pcs_ctrl(PARALLEL_PCS_DSG_EN);
    input_reg2_buf[16] = parallel_get_pcs_ctrl(PARALLEL_PCS_CHG_EN);
}

static uint16_t smk_get_sys_state(void)
{
	uint16_t state = 0;
	
	if(parallel_get_pcs_ctrl(PARALLEL_PCS_FROCE_CHG1))
		state |= (1 << 12);
	if(parallel_get_pcs_ctrl(PARALLEL_PCS_CHG_EN))
		state |= (1 << 6);
	if(parallel_get_pcs_ctrl(PARALLEL_PCS_DSG_EN))
		state |= (1 << 5);
	
	return state;
}
/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/
